﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Xml.Linq;
using System.Text;

namespace VisualRibbonEditor
{
	/// <summary>
	/// ElementEditor is used when editing Actions, EnableRules, and DisplayRules for
	/// a ribbon control.  Each ElementEditor control is linked to an XML Element in the ribbon xml file
	/// and they are arranged in a TreeView style structure on the page, allowing the user to
	/// edit the attributes of the current element or add child Elements underneath the current element.
	///
	/// Note: there are a few special cases where the ribbonXml for actions and rules doesnt follow
	/// a simple hierarchical structure:
	/// 1. The OrRule element has "Or" elements inside it which are reduntant from a UI perspective so we skip past them and
	///    the user never sees an "Or element.
	/// 2. The EnableRule and DisplayRule elements in the CommandDefiniton are just pointers to the real rules defined
	///    in the RuleDefinitions section, so we have to look up the real rule in the RuleDefinitions to get its attrubures and child elements.
	/// </summary>
	public partial class ElementEditor : UserControl
	{

		private bool _editable;

		public ElementEditor()
		{
			InitializeComponent();
		}

		/// <summary>
		/// constructor
		/// </summary>
		/// <param name="element"></param>
		/// <param name="editable"></param>
		public ElementEditor(XElement element, bool editable)
		{
			InitializeComponent();

			Expanded = false;
			NewPopup.IsOpen = false;

			SourceElement = element;
			_editable = editable;

			//special case for DisplayRule and EnableRule
			if (element.Name.LocalName == "DisplayRule" || element.Name.LocalName == "EnableRule")
			{
				//SourceElement will be the real element in RuleDefinitions
				//and PointerElement will be the pointer element in the CommandDefinition.
				string id = element.Attribute("Id").Value;
				XElement root = element.Ancestors().Last();
				XElement RuleDefinitions = root.Descendants("RuleDefinitions").First();
				XElement realElement = RuleDefinitions.Descendants(element.Name.LocalName).Where(x => x.Attribute("Id").Value == id).First();
				PointerElement = element;
				SourceElement = realElement.Elements().First();
			}

			//special case for "Or" elements
			if (element.Name.LocalName == "Or")
			{
				//pointer is the "Or" and Source is the actual rule inside the "Or"
				PointerElement = element;
				SourceElement = element.Elements().First();
			}

			//set UI stuff: names, labels, tooltips etc.
			this.NameLabel.Text = SourceElement.Name.LocalName;
			ToolTipService.SetToolTip(NameLabel, SourceElement.Name.LocalName);
			EvaluateDescription();
			this.DeleteButton.ToolTip = "Remove this " + SourceElement.Name.LocalName;

			//load the items that can be added as a child of this element (i.e., what we see in the "new" popup)
			LoadNewList();

			//load the attributes table
			LoadAttributes();

			//load all child elements (this will recursively add more ElementEditors as children of this control)
			LoadChildren();

			//hide the new and remove buttons if this isnt an editable element
			if (!editable)
			{
				DeleteButton.Visibility = System.Windows.Visibility.Collapsed;
				NewButton.Visibility = System.Windows.Visibility.Collapsed;
			}
		}

		public XElement PointerElement { get; set; }
		public XElement SourceElement { get; set; }

		private bool _expanded;
		public bool Expanded
		{
			get { return _expanded; }
			set
			{
				_expanded = value;
				RightArrow.Visibility = _expanded ? Visibility.Collapsed : Visibility.Visible;
				DownArrow.Visibility = _expanded ? Visibility.Visible : Visibility.Collapsed;
				DetailStack.Visibility = _expanded ? Visibility.Visible : Visibility.Collapsed;
				if (!_expanded)
				{
					NewPopup.IsOpen = false;
				}
			}
		}

		private bool _canBeDeleted = true;
		public bool CanBeDeleted
		{
			get { return _canBeDeleted; }
			set
			{
				_canBeDeleted = value;
				if (_canBeDeleted && _editable)
				{
					this.DeleteButton.Visibility = System.Windows.Visibility.Visible;
				}
				else
				{
					this.DeleteButton.Visibility = System.Windows.Visibility.Collapsed;
				}
			}
		}

		/// <summary>
		/// User clicks the expander arrow.
		/// </summary>
		private void Arrow_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
		{
			//toggle expansion
			Expanded = !Expanded;
		}

		/// <summary>
		/// User clicks Remove button
		/// </summary>
		private void DeleteButton_Click(object sender, RoutedEventArgs e)
		{
			XElement parent;
			if (PointerElement != null)
			{
				//if there's a pointer element then remove it from the xml
				parent = PointerElement.Parent;
				PointerElement.Remove();
			}
			else
			{
				//otherwise we can just delete the sourceElement from xml
				parent = SourceElement.Parent;
				SourceElement.Remove();
			}

			SourceElement = parent; //set sourceElement to the parent so that UpdateRibbonDiffXml will work.
			UpdateRibbonDiffXml();

			//special case for DisplayRule and EnableRule
			//the pointer from the commandDefinition is already deleted but the actual rule needs to
			//be deleted from the RuleDefinitions section too.
			if( PointerElement != null &&
			 (PointerElement.Name.LocalName == "DisplayRule" || PointerElement.Name.LocalName == "EnableRule"))
			{
				DeleteRule(PointerElement.Attribute("Id").Value, PointerElement.Name.LocalName);
			}

			//Finally, we can remove this control from the visual tree
			Panel p = (Panel)this.Parent;
			p.Children.Remove(this);
		}

		/// <summary>
		/// User clicks new.
		/// </summary>
		private void NewButton_Click(object sender, RoutedEventArgs e)
		{
			//show the newpopup (list of elements that can be added below this element)
			this.NewPopup.IsOpen = true;

			//hilight the first menu item
			Border first = (Border)NewButtonStack.Children[0];
			HilightMenuItem(first);

			App.Current.MainWindow.MouseLeftButtonDown += HidePopup;
			e.Handled = true;
		}

		void HidePopup(object sender, MouseButtonEventArgs e)
		{
			NewPopup.IsOpen = false;
			App.Current.MainWindow.MouseLeftButtonDown -= HidePopup;
		}



		/// <summary>
		/// User selects an option from the newpopup.
		/// </summary>
		void NewButton_SelectOption(object sender, MouseButtonEventArgs e)
		{
			TextBlock tb = (TextBlock)sender;
			string newElementName = tb.Tag.ToString();
			string sourceElementName = SourceElement.Name.LocalName;

			//special cases:
			if (sourceElementName == "DisplayRules" || sourceElementName == "EnableRules")
			{
				//add a <DisplayRule> element thats just a pointer to the real rule inside the rules section.
				AddRulePointer(newElementName);
			}
			else if (sourceElementName == "OrRule")
			{
				//for OrRules, you need an <Or> element, then the added rule inside of it.
				XElement OrElement = new XElement("Or");
				SourceElement.Add(OrElement);

				XElement newElement = new XElement(newElementName);
				OrElement.Add(newElement);
			}
			else
			{
				XElement newElement = new XElement(newElementName);
				if (sourceElementName == "JavaScriptFunction" && newElementName == "StringParameter") newElement.Add(new XAttribute("Value", String.Empty));
				SourceElement.Add(newElement);
			}

			UpdateRibbonDiffXml();

			//close the popup and re-load all child controls
			NewPopup.IsOpen = false;
			LoadChildren();

			//expand the child we just added (it will be the last one)
			ElementEditor lastChild = (ElementEditor) this.ChildElements.Children[this.ChildElements.Children.Count - 1];
			this.Expanded = true;
			lastChild.Expanded = true;
		}

		/// <summary>
		/// Adds a DisplayRule or EnableRule to the commandDefinitoon and then also adds th real rule to the
		/// RuleDefinitions section
		/// </summary>
		private void AddRulePointer(string newRuleType)
		{
			string ruleCategory = this.SourceElement.Name.LocalName == "DisplayRules" ? "DisplayRule" : "EnableRule";

			XElement root = SourceElement.Ancestors().Last();
			XElement RuleDefinitions = root.Descendants("RuleDefinitions").First();
			XElement Rules = RuleDefinitions.Element(SourceElement.Name.LocalName);

			//get the id of the new element
			string id = SourceElement.Parent.Attribute("Id").Value + "." + ruleCategory + "." + newRuleType;
			int i = 1;
			while (Rules.Elements().Attributes("Id").Count(x => x.Value == id) > 0)
			{
				i++;
				id = SourceElement.Parent.Attribute("Id").Value + "." + ruleCategory + "." + newRuleType + i.ToString();
			}

			//add the pointer
			XElement displayRulePointer = new XElement(ruleCategory);
			displayRulePointer.Add(new XAttribute("Id", id));
			SourceElement.Add(displayRulePointer);

			//add the displayRule element inside the displayrules collection.
			XElement displayRule = new XElement(ruleCategory);
			displayRule.Add(new XAttribute("Id", id));
			Rules.Add(displayRule);

			//add the new rule element
			XElement rule = new XElement(newRuleType);
			displayRule.Add(rule);

			//add the new rule to the RibbonDiffXml too
			XElement diffRuleCollection = MainWindow.CurrentSolution.RibbonDiffXml.Descendants("RuleDefinitions").Elements(SourceElement.Name.LocalName).First();

			//add the displayRule element inside the displayrules collection.
			XElement diffDisplayRule = new XElement(ruleCategory);
			diffDisplayRule.Add(new XAttribute("Id", id));
			diffRuleCollection.Add(displayRule);

			//add the new rule element
			XElement diffRule = new XElement(newRuleType);
			diffDisplayRule.Add(rule);
		}

		/// <summary>
		/// Updates the description text for this control based on the values of the element attributes.
		/// </summary>
		private void EvaluateDescription()
		{
			Dictionary<string, ElementType> elementTypes = Meta.GetElementTypes();
			if (!elementTypes.ContainsKey(SourceElement.Name.LocalName))
			{
				return;
			}
			ElementType elType = elementTypes[SourceElement.Name.LocalName];
			if (elType.TextFormat != null)
			{
				string text = elType.TextFormat;
				foreach (XAttribute att in SourceElement.Attributes())
				{
					text = text.Replace("{" + att.Name.LocalName + "}", att.Value);
				}

				XAttribute InvertResult = SourceElement.Attribute("InvertResult");
				if (InvertResult != null && InvertResult.Value == "true")
				{
					text = text.Replace("{=}", "!=");
					text = text.Replace("{has}", "does not have");
					text = text.Replace("{is}", "is not");
				}
				else
				{
					text = text.Replace("{=}", "=");
					text = text.Replace("{has}", "has");
					text = text.Replace("{is}", "is");
				}

				NameLabel.Text = RemoveTags(text);
			}
		}

		/// <summary>
		/// Removes all {} tags from the string
		/// </summary>
		private string RemoveTags(string s)
		{
			bool inTag = false;
			StringBuilder sb = new StringBuilder();
			for( int i = 0; i < s.Length; i++)
			{
				if (s[i] == '{')
					inTag = true;

				if( !inTag)
				{
					sb.Append(s[i]);
				}

				if (s[i] == '}')
					inTag = false;
			}

			return sb.ToString();
		}

		/// <summary>
		/// Loads the "new" list. items the user will see in the dropdown when they click the "new" button.
		/// </summary>
		private void LoadNewList()
		{
			Dictionary<string, ElementType> elementTypes = Meta.GetElementTypes();

			string elementName = SourceElement.Name.LocalName;
			if (elementName == "DisplayRules") elementName = "DisplayRule";
			if (elementName == "EnableRules") elementName = "EnableRule";
			if (elementName == "OrRule") elementName = "Or";

			ElementType elType = elementTypes[elementName];

			NewButton.ToolTip = elType.NewChildTooltip;

			if (elType.ChildElements != null && elType.ChildElements.Length > 0)
			{
				NewButtonStack.Children.Clear();
				foreach (string childType in elType.ChildElements)
				{
					Border menuItemBorder = new Border();
					//menuItemBorder.BorderBrush = new SolidColorBrush(Helpers.GetColorFromHexa("#FFF1C43F")); //gold border
					menuItemBorder.BorderBrush = new SolidColorBrush(Colors.White);
					menuItemBorder.BorderThickness = new Thickness(1);
					menuItemBorder.Tag = childType;
					menuItemBorder.Padding = new Thickness(1);

					NewButtonStack.Children.Add(menuItemBorder);

					menuItemBorder.MouseEnter += new MouseEventHandler(menuItemBorder_MouseEnter);

					TextBlock menuItemText = new TextBlock();
					menuItemText.Text = childType;
					menuItemText.Tag = childType;
					menuItemText.MouseLeftButtonDown += new MouseButtonEventHandler(NewButton_SelectOption);
					menuItemBorder.Child = menuItemText;
				}

				//hilight the first menu item
				Border first = (Border) NewButtonStack.Children[0];
				HilightMenuItem(first);

				NewButton.Visibility = System.Windows.Visibility.Visible;
			}
			else
			{
				NewButton.Visibility = System.Windows.Visibility.Collapsed;
			}
		}



		private Border _currentMenuItemBorder = null;

		void menuItemBorder_MouseEnter(object sender, MouseEventArgs e)
		{
			Border border = (Border)sender;
			HilightMenuItem(border);
		}

		private void HilightMenuItem(Border border)
		{
			if (_currentMenuItemBorder != border)
			{
				if (_currentMenuItemBorder != null)
				{
					_currentMenuItemBorder.BorderBrush = new SolidColorBrush(Colors.White);
					_currentMenuItemBorder.Background = new SolidColorBrush(Colors.Transparent);
				}

				_currentMenuItemBorder = border;

				border.BorderBrush = new SolidColorBrush(Helpers.GetColorFromHexa("#FFF1C43F")); //gold border
				border.Background = new SolidColorBrush(Helpers.GetColorFromHexa("#FFFDEEB3"));

				string type = border.Tag.ToString();
				var types = Meta.GetElementTypes();
				NewMenuDescription.Text = types[type].Description;

				//set the top-margin of the description so it lines up with the currently hilighted menu item.
				int c = 0;
				foreach (Border b in NewButtonStack.Children)
				{
					if (b == border)
					{
						break;
					}
					c++;
				}
				int total = NewButtonStack.Children.Count;
				if (c > total - 2)
				{
					c = Math.Max(0, total - 2);
				}

				var offset = border.ActualHeight * c;
				NewMenuDescription.Margin = new Thickness(0, offset, 0, 0);
			}
		}

		/// <summary>
		/// Creates and adds new ElementEditors for each of the child Elements of this element.
		/// </summary>
		private void LoadChildren()
		{
			ChildElements.Children.Clear();

			Dictionary<string, ElementType> elementTypes = Meta.GetElementTypes();
			foreach (XElement element in SourceElement.Elements())
			{
				if (elementTypes.ContainsKey(element.Name.LocalName))
				{
					ElementEditor childElementEditor = new ElementEditor(element, _editable);
					ChildElements.Children.Add(childElementEditor);
				}
			}
		}

		/// <summary>
		/// Builds the attributes table.
		/// (generates an input table that allows the user to fill out values for each of the editable attributes of the Element)
		/// </summary>
		private void LoadAttributes()
		{
			XElement element = SourceElement;
			Dictionary<string, ElementType> elementTypes = Meta.GetElementTypes();
			ElementType elType = elementTypes[element.Name.LocalName];

			DetailGrid.Children.Clear();

			if (elType.Attributes != null && elType.Attributes.Length > 0)
			{
				DetailGridBorder.Visibility = System.Windows.Visibility.Visible;

				//Special case: if elements parent is JavaScriptFunction then it should not have a "Name" attribute.
				IEnumerable<AttributeType> attributes = elType.Attributes;
				if (element.Parent.Name.LocalName == "JavaScriptFunction")
				{
					attributes = attributes.Where(x => x.AttributeName != "Name");
				}

				int i = 1;
				foreach (AttributeType at in attributes)
				{
					TextBlock tb = new TextBlock();
					tb.Text = Helpers.AddSpaces(at.AttributeName);
					if (at.IsRequired)
					{
						tb.FontWeight = FontWeights.Bold;
						tb.Text += "*: ";
						tb.ToolTip = "Required";
					}
					else
					{
						tb.Text += ": ";
					}

					tb.VerticalAlignment = System.Windows.VerticalAlignment.Center;
					Grid.SetRow(tb, i);
					DetailGrid.Children.Add(tb);

					XAttribute attribute = element.Attribute(at.AttributeName);

					if (DetailGrid.RowDefinitions.Count <= i)
					{
						DetailGrid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) });
					}

					if (at.FreeText)
					{
						// Autocomplete textbox for JavaScript libraries
						if (elType.ElementName == "JavaScriptFunction" && at.AttributeName == "Library" && _editable)
						{

							StackPanel sp = new StackPanel();
							sp.Orientation = Orientation.Horizontal;

							// Create autocomplete control
							AutoCompleteBox ab = new AutoCompleteBox();
							if (attribute != null && attribute.Value != null)
							{
								ab.Text = attribute.Value;
							}
							ab.Margin = new Thickness(2);
							ab.MinWidth = 300;
							ab.Tag = new Tuple<XElement, string>(element, at.AttributeName);
							ab.TextChanged += new RoutedEventHandler(ab_TextChanged);

							WebResourceManager.SetupScriptAutoComplete(ab);

							// Create Browse button
							Button b = new Button();
							b.Content = "...";
							b.Height = 20;
							b.ToolTip = "Select a script...";
							b.HorizontalAlignment = HorizontalAlignment.Left;
							b.Margin = new Thickness(2);
							b.Width = 20;
							b.Click += (source, e) =>
							{
								WebResourceDialog webResourceDialog = new WebResourceDialog(ResourceType.Script, ab.Text.Replace("$webresource:", ""));
								MainWindow.CurrentMainPage.ShowPopupDialog(webResourceDialog, (result) =>
								{
									if (result != null)
									{
										ab.Text = "$webresource:" + result.ToString();
									}
								});
							};

							sp.Children.Add(ab);
							sp.Children.Add(b);

							Grid.SetRow(sp, i);
							Grid.SetColumn(sp, 1);
							DetailGrid.Children.Add(sp);
						}
						else
						{
							TextBox tbox = new TextBox();
							if (attribute != null && attribute.Value != null)
							{
								tbox.Text = attribute.Value;
							}
							tbox.Margin = new Thickness(2);
							tbox.MinWidth = 300;
							tbox.Tag = new Tuple<XElement, string>(element, at.AttributeName);
							tbox.TextChanged += new TextChangedEventHandler(tbox_TextChanged);
							tbox.IsReadOnly = !_editable;

							Grid.SetRow(tbox, i);
							Grid.SetColumn(tbox, 1);
							DetailGrid.Children.Add(tbox);
						}
					}
					else
					{
						ComboBox combo = new ComboBox();
						combo.Items.Add(new ComboBoxItem() { Content = " " });
						for ( int j = 0; j < at.OptionValues.Length; j++)
						{
							ComboBoxItem item = new ComboBoxItem();
							item.Tag = at.OptionValues[j];
							if (at.OptionDisplayNames != null)
							{
								item.Content = at.OptionDisplayNames[j];
							}
							else
							{
								item.Content = at.OptionValues[j];
							}
							if (attribute != null && attribute.Value == at.OptionValues[j])
							{
								item.IsSelected = true;
							}
							combo.Items.Add(item);
						}

						combo.Margin = new Thickness(2);
						combo.MinWidth = 300;
						combo.Tag = new Tuple<XElement, string>(element, at.AttributeName);

						combo.IsEnabled = _editable;
						combo.SelectionChanged += new SelectionChangedEventHandler(AttributeComboSelectionChanged);
						Grid.SetRow(combo, i);
						Grid.SetColumn(combo, 1);
						DetailGrid.Children.Add(combo);
					}
					i++;
				}
			}
			else
			{
				//this element doesnt have attributes
				DetailGridBorder.Visibility = System.Windows.Visibility.Collapsed;
			}
		}

		void AttributeComboSelectionChanged(object sender, SelectionChangedEventArgs e)
		{
			ComboBox cbox = (ComboBox)sender;
			Tuple<XElement, string> tag = (Tuple<XElement, string>)cbox.Tag;
			XElement element = tag.Item1;
			string attributeName = tag.Item2;

			ComboBoxItem item = (ComboBoxItem) cbox.SelectedItem;
			if (item == null || item.Tag == null)
			{
				element.SetAttributeValue(attributeName, null);
			}
			else
			{
				element.SetAttributeValue(attributeName, item.Tag.ToString());
			}

			EvaluateDescription();
			UpdateRibbonDiffXml();
		}

		void ab_TextChanged(object sender, RoutedEventArgs e)
		{
			AutoCompleteBox tb = (AutoCompleteBox)sender;
			Tuple<XElement, string> tag = (Tuple<XElement, string>)tb.Tag;

			if (string.IsNullOrEmpty(tb.Text))
			{
				if (tag.Item1.Name.LocalName == "StringParameter" && tag.Item2 == "Value")
					tag.Item1.SetAttributeValue(tag.Item2, String.Empty);
				else
					tag.Item1.SetAttributeValue(tag.Item2, null);
			}
			else
			{
				tag.Item1.SetAttributeValue(tag.Item2, tb.Text);
			}

			EvaluateDescription();
			UpdateRibbonDiffXml();
		}

		void tbox_TextChanged(object sender, TextChangedEventArgs e)
		{
			TextBox tb = (TextBox)sender;
			Tuple<XElement,string> tag = (Tuple<XElement,string>) tb.Tag;

			if (string.IsNullOrEmpty(tb.Text))
			{
				if (tag.Item1.Name.LocalName == "StringParameter" && tag.Item2 == "Value")
					tag.Item1.SetAttributeValue(tag.Item2, String.Empty);
				else
					tag.Item1.SetAttributeValue(tag.Item2, null);
			}
			else
			{
				tag.Item1.SetAttributeValue(tag.Item2, tb.Text);
			}

			EvaluateDescription();
			UpdateRibbonDiffXml();
		}

		private void UpdateRibbonDiffXml()
		{
			var ancestorWithId = SourceElement.AncestorsAndSelf().Where(x => x.Attribute("Id") != null).First();

			CopyXmlToRibbonDiff(ancestorWithId);
		}

		/// <summary>
		/// Copies XML from the BaseRibbon to the RibbonDiffXml in the current solution
		/// </summary>
		private void CopyXmlToRibbonDiff(XElement element)
		{
			string elementName = element.Name.LocalName;
			string elementId = element.Attribute("Id").Value;

			if (elementName == "CommandDefinition")
			{
				XElement matchingElement = MainWindow.CurrentSolution.RibbonDiffXml.Descendants("CommandDefinition")
					.Where(x => x.Attribute("Id").Value == elementId).First();
				matchingElement.ReplaceWith(element);
			}
			if (elementName == "DisplayRule")
			{
				XElement DisplayRules = MainWindow.CurrentSolution.RibbonDiffXml.Descendants("RuleDefinitions").Elements("DisplayRules").First();
				XElement matchingElement = DisplayRules.Elements("DisplayRule")
					.Where(x => x.Attribute("Id").Value == elementId).First();
				matchingElement.ReplaceWith(element);
			}
			if (elementName == "EnableRule")
			{
				XElement EnableRules = MainWindow.CurrentSolution.RibbonDiffXml.Descendants("RuleDefinitions").Elements("EnableRules").First();
				XElement matchingElement = EnableRules.Elements("EnableRule")
					.Where(x => x.Attribute("Id").Value == elementId).First();
				matchingElement.ReplaceWith(element);
			}
		}

		private void DeleteRule(string ruleId, string type)
		{
			DeleteRule(ruleId, type, MainWindow.CurrentSolution.RibbonDiffXml); //delete it in the diffxml
			DeleteRule(ruleId, type, SourceElement.Ancestors().Last()); //delete it in the base xml
		}

		private void DeleteRule(string ruleId, string type, XElement rootElement)
		{
			string collectionName = type + "s"; //will be either "DisplayRules" or "EnableRules";

			//find all commandDefinitions that use this rule
			var UsesOfRule = rootElement.Descendants("CommandDefinition")
				.Elements(collectionName).Elements(type).Where(x => x.Attribute("Id").Value == ruleId);

			//only actually delete the rule if its not used by any other commandDefinitions
			if (UsesOfRule.Count() == 0)
			{
				XElement rulesCollection = rootElement.Descendants("RuleDefinitions").Elements(collectionName).First();
				XElement rule = rulesCollection.Elements(type).Where(x => x.Attribute("Id").Value == ruleId).First();
				rule.Remove();
			}
		}

		private void DeleteButton_KeyDown(object sender, KeyEventArgs e)
		{
			if( e.Key == Key.Enter)
			{
				DeleteButton_Click(sender, new RoutedEventArgs());
			}
		}

		private void NewButton_KeyDown(object sender, KeyEventArgs e)
		{
			if (e.Key == Key.Enter)
			{
				NewButton_Click(sender, new RoutedEventArgs());
			}
		}
	}
}